open Utils.Pervasive
open Utils.ListSpecial
open Utils.StringSpecial

open ProofAssembler
open BlockPopulation
open Binding
open Population
open Gobject.Data

let cols = new GTree.column_list
let idCol = cols#add string
let aidCol = cols#add string
let bg = cols#add (unsafe_boxed (Gobject.Type.from_name "GdkColor"))

let updateModel eco ~(model : GTree.tree_store) speciesLst = 
		begin try let iter = model#iter_children ~nth:0 None in
			let remove = ref (model#remove iter) in
			while !remove do
				remove := model#remove iter 
			done
		with _->( ) end;
		
		ListLabels.iter speciesLst
		~f:(fun ((id,_),_) ->
			let row = model#append ( ) in 
			let set column = model#set ~row ~column in 
			let color str = set bg (GDraw.color (`NAME str)) in
			set idCol (string_of_int id))
	
			
let add_columns ~(view : GTree.view) ~model =
  let renderer = GTree.cell_renderer_text [`XALIGN 0.] in
  ListLabels.iter 
  [("ID" , idCol) ;  
  ("Ancestor" , aidCol)]
  ~f: (fun (title, col) -> 
			let col_view = GTree.view_column ~title
			~renderer:(renderer, [("text", col)]) ( ) in
			col_view#add_attribute renderer "background-gdk" bg;
			un(view#append_column col_view))
let on_row_activated ?(debug=false) eco (view:GTree.view) path column = 
	let model = view#model in
	let row = model#get_iter path in
	let str = model#get ~row ~column:idCol in
	try 
		let id = int_of_string str in
		let species = get_species_from_id eco id in
		prf ~filename:(Some "tree.dot") (string_of_proof  ~output:"dot" (gpContext !(eco.genes)) species);
		command "dot -Tgif tree.dot -o out.gif | out.gif"
	with
	|_->( )
let create_model ( ) =
  let model = GTree.tree_store cols in
  model
let make_proof_visual eco (id, species) = 
	(*Window settings***************)
	let speciesLst = ref [((id, None),  species)] in
	let window = GWindow.window ~title:"proofs" () in
		window#set_default_size ~width:950 ~height:700;
	
	let hBox = GPack.hbox ~packing:window#add () in
	let leftPanel = GPack.vbox 
		~border_width:8 
		~height:350 
		~width:500 
		~spacing:8 
		~packing:hBox#add () in    
	let sw_progs, model = 
	GBin.scrolled_window 
		~shadow_type:`ETCHED_IN ~hpolicy:`AUTOMATIC 
		~vpolicy:`AUTOMATIC ~packing:leftPanel#add (), 
	create_model ( ) in
	let view = GTree.view ~model:model ~packing:sw_progs#add () in 
		view#set_rules_hint true; 
		view#selection#set_mode `MULTIPLE; 
		add_columns ~view ~model;
	let boxMenu = GPack.vbox ~width:80 ~packing:hBox#add () in
	let panel ?(box = boxMenu) title = 
		let pan = GBin.frame ~label:(title^ "...") ~packing:box#pack ( ) in
		GPack.vbox ~width:80 ~packing:pan#add ( ) in
	let controlPanel = panel "Tests..." in
	let empty_entry ?(editable=false) ?(text="") packer ( ) = 
		GEdit.entry ~editable ~text  ~width:100  ~packing:packer#add ( ) in
    let button str packer ( ) = GButton.button ~label:str ~packing:packer#add () in
	
	let depthEdit, goButton =
		empty_entry ~text:"1" ~editable:true controlPanel ( ), 
		button "Modify" controlPanel ( ) in
	
	let doEvolution( ) = 
		let depth = int_of_string(depthEdit#text) in
		let newSpecies = modifyProofs ~proofs:[species] eco depth in
		let genes = !(eco.genes) in
		let add ( ) = 
			ListLabels.fold_left newSpecies ~init:[]
			~f:(fun acc (ancesterID, proof) -> 
			if not (ProofAssembler.exists (gpContext genes) (keys eco.kingdom) proof) 
			then ((add_species eco proof ancesterID), proof) :: acc 
			else acc) in
		speciesLst :=  ((id, None), species)::add( ); 
		updateModel eco ~model !speciesLst;
		
		in
		
	
	
	updateModel eco ~model !speciesLst;	
	un(view#connect#row_activated ~callback:(on_row_activated eco view));
	un(goButton#connect#clicked ~callback:doEvolution);
	
	window#show()
